package com.example.siteservices.demos.web;

import com.example.siteservices.dto.*;
import com.example.siteservices.entity.File;
import com.example.siteservices.service.FileService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.example.siteservices.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;

import com.example.siteservices.service.BrowserFingerprintService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 控制器类，用于处理基本的HTTP请求。
 * 包含处理不同请求路径的多个方法，返回简单的字符串消息或用户对象。
 */
@CrossOrigin(
    origins = "*",
    allowedHeaders = "*",
    methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, 
               RequestMethod.DELETE, RequestMethod.OPTIONS},
    maxAge = 3600
)
@Controller
public class BasicController {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserService userService;
    @Autowired
    private FileService fileService;
    @Autowired
    private BrowserFingerprintService fingerprintService;

    /**
     * 生成指纹的私有方法
     */
    private String generateFingerprint(String userAgent, String language, String clientIp) {
        // 组合所有信息
        String combinedInfo = userAgent + language + clientIp;

        try {
            // 使用MD5生成指纹
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(combinedInfo.getBytes(StandardCharsets.UTF_8));

            // 转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }

            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            // 如果MD5算法不可用，返回简单的hash码
            return String.valueOf(combinedInfo.hashCode());
        }
    }

    /**
     * 处理浏览器指纹的私有方法
     */
    private void handleBrowserFingerprint(HttpServletRequest request) {
        try {
            String userAgent = request.getHeader("User-Agent");
            String language = request.getHeader("Accept-Language");
            String clientIp = getClientIp(request);

            BrowserFingerprintDTO fingerprint = new BrowserFingerprintDTO();
            fingerprint.setUserAgent(userAgent);
            fingerprint.setLanguage(language);

            String uniqueFingerprint = generateFingerprint(userAgent, language, clientIp);
            fingerprint.setFingerprint(uniqueFingerprint);

            // 保存或更新指纹信息
            fingerprintService.saveOrUpdateFingerprint(fingerprint, clientIp);
        } catch (Exception e) {
            // 记录错误但不影响主要业务流程
            logger.error("Failed to handle browser fingerprint: ", e);
        }
    }

    /**
     * 获取客户端真实IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        // 多个代理的情况，第一个IP为客户端真实IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0];
        }

        return ip;
    }

    /**
     * 处理"/hello"路径的GET请求，返回问候消息。
     *
     * @param name 请求参数中的名字，默认为"unknown user"。
     * @return 返回问候消息，包含请求参数中的名字。
     */
    // http://127.0.0.1:8080/hello?name=lisi
    @RequestMapping("/hello")
    @ResponseBody
    public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name) {
        return "Hello " + name;
    }

    /**
     * 处理"/user"路径的GET请求，返回一个用户对象。
     *
     * @return 返回一个包含默认用户名和年龄的用户对象。
     */
    // http://127.0.0.1:8080/user
    @RequestMapping("/user")
    @ResponseBody
    public User user() {
        User user = new User();
        user.setName("theonefx");
        user.setAge(666);
        return user;
    }

    /**
     * 处理"/save_user"路径的GET请求，接收用户参数并返回保存信息。
     *
     * @param u 从请求参数中构建的用户对象。
     * @return 返回用户保存的信息，包含用户的名称和年龄。
     */
    // http://127.0.0.1:8080/save_user?name=newName&age=11
    @RequestMapping("/save_user")
    @ResponseBody
    public String saveUser(User u) {
        return "user will save: name=" + u.getName() + ", age=" + u.getAge();
    }

    /**
     * 处理"/html"路径的GET请求，返回一个HTML页面的名称。
     *
     * @return 返回要渲染的HTML页面的名称。
     */
    // http://127.0.0.1:8080/html
    @RequestMapping("/html")
    public String html(){
        return "index.html";
    }

    /**
     * 在处理请求前，将请求参数绑定到用户对象。
     * 此方法主要用于在控制器的方法之间共享模型属性。
     *
     * @param name 请求参数中的名字，默认为"unknown user"。
     * @param age 请求参数中的年龄，默认为12。
     * @param user 要填充的用户对象。
     */
    @ModelAttribute
    public void parseUser(@RequestParam(name = "name", defaultValue = "unknown user") String name
            , @RequestParam(name = "age", defaultValue = "12") Integer age, User user) {
        user.setName("zhangsan");
        user.setAge(18);
    }

    /**
     * 处理用户登录请求
     */
    @PostMapping("/login")
    @ResponseBody
    public ApiResponse login(@RequestBody LoginRequest loginRequest, HttpServletRequest request) {
        try {
            // 处理浏览器指纹
            handleBrowserFingerprint(request);
            
            boolean success = userService.login(loginRequest);
            if (success) {
                return ApiResponse.success("登录成功");
            } else {
                return ApiResponse.error("登录失败：用户名或密码错误");
            }
        } catch (Exception e) {
            return ApiResponse.error("登录失败：" + e.getMessage());
        }
    }

    /**
     * 处理"/fileList"路径的POST请求，接收筛选条件并返回文件列表。
     */
    @PostMapping("/fileList")
    @ResponseBody
    public ApiResponse fileListWithFilters(@RequestBody FileFilterRequest fileFilterRequest, 
                                         HttpServletRequest request) {
        try {
            // 处理浏览器指纹
            handleBrowserFingerprint(request);
            
            List<FileRequest> files = fileService.getAllFilesWithFilters(fileFilterRequest);
            
            Map<String, Object> data = new HashMap<>();
            data.put("data", files);
            data.put("success", true);
            data.put("total", files.size());
            data.put("current", fileFilterRequest.getCurrent());
            data.put("pageSize", fileFilterRequest.getPageSize());
            
            return ApiResponse.success(data);
        } catch (Exception e) {
            return ApiResponse.error("获取文件列表失败：" + e.getMessage());
        }
    }

    @PostMapping("/uploadFileList")
    @ResponseBody
    public ApiResponse photoFileList(@RequestBody PhotoFileRequest fileRequest,
                                  HttpServletRequest request) {
        try {
            // 处理浏览器指纹
            handleBrowserFingerprint(request);

            List<FileRequest> files = fileService.getPhotoFilesList(fileRequest);



            Map<String, Object> data = new HashMap<>();
            data.put("data", files);
            data.put("success", true);
            data.put("total", files.size());
            data.put("current", fileRequest.getCurrent());
            data.put("pageSize", fileRequest.getPageSize());
            return ApiResponse.success(data);
        } catch (Exception e) {
            return ApiResponse.error("获取图片文件列表失败：" + e.getMessage());
        }
    }


    /**
     * 处理"/fileUpload"路径的POST请求，实现文件上传。
     */
    @PostMapping("/fileUpload")
    @ResponseBody
    public ApiResponse fileUpload(@RequestParam("file") MultipartFile file, 
                                HttpServletRequest request) {
        try {
            // 处理浏览器指纹
            handleBrowserFingerprint(request);
            
            String filePath = fileService.uploadFile(file);
            
            Map<String, Object> data = new HashMap<>();
            data.put("filePath", filePath);
            data.put("success", true);
            
            return ApiResponse.success(data);
        } catch (Exception e) {
            return ApiResponse.error("文件上传失败：" + e.getMessage());
        }
    }

    /**
     * 处理"/saveFileInfo"路径的POST请求，保存文件信息。
     */
    @PostMapping("/saveFileInfo")
    @ResponseBody
    public ApiResponse saveFileInfo(@RequestBody FileRequest fileRequest, 
                                  HttpServletRequest request) {
        try {
            // 处理浏览器指纹
            handleBrowserFingerprint(request);
            
            FileRequest savedFile = fileService.saveFileInfo(fileRequest);
            
            Map<String, Object> data = new HashMap<>();
            data.put("fileInfo", savedFile);
            data.put("success", true);
            
            return ApiResponse.success(data);
        } catch (Exception e) {
            return ApiResponse.error("文件信息保存失败：" + e.getMessage());
        }
    }

    /**
     * 获取浏览器指纹
     * @param request HTTP请求对象
     * @return 返回浏览器指纹信息
     */
    @GetMapping("/getBrowserFingerprint")
    @ResponseBody
    public ApiResponse getBrowserFingerprint(HttpServletRequest request) {
        try {
            BrowserFingerprintDTO fingerprint = new BrowserFingerprintDTO();
            
            String userAgent = request.getHeader("User-Agent");
            String language = request.getHeader("Accept-Language");
            String clientIp = request.getRemoteAddr();
            
            fingerprint.setUserAgent(userAgent);
            fingerprint.setLanguage(language);
            
            String uniqueFingerprint = generateFingerprint(userAgent, language, clientIp);
            fingerprint.setFingerprint(uniqueFingerprint);
            
            // 保存或更新指纹信息
            fingerprintService.saveOrUpdateFingerprint(fingerprint, clientIp);
            
            return ApiResponse.success(fingerprint);
        } catch (Exception e) {
            return ApiResponse.error("获取浏览器指纹失败：" + e.getMessage());
        }
    }


}
